package progress.exa27_3;

import java.util.ArrayList;
import java.util.List;

/**
 * 此类将包含关于ArrayList中主要方法的性能测试
 */
public class ArrayListStudy {
    public static void main(String[] args) {
        List<Integer> list = addTest(100000);
        System.out.println("修改耗时："+updateTest(list)+"ms");
        System.out.println("查询耗时： "+queryTest(list)+"ms");
        System.out.println("插入耗时： "+insertTest(list)+"ms");
        System.out.println("删除耗时： "+deleteTest(list)+"ms");
    }

    /**
     * 添加性能测试，ArrayList中add方法默认向数组尾部添加元素，
     * 所以它的时间复杂度一般为常数O(1) 【扩容会消耗一定的时间，但基本可以忽略不记(次数极少)】
     * @param num
     * @return
     */
    public static List<Integer> addTest(int num){
        long start = System.currentTimeMillis();
        ArrayList<Integer> list = new ArrayList<>();
        for(int i=0;i<num;i++){
            list.add(i);
        }
        System.out.println("添加耗时："+ (System.currentTimeMillis()-start)+ "ms");
        return list;
    }

    /**
     * 插入性能测试，这个方法的性能随着插入的位置不同，如果插入的位置是尾部，则它的时间复杂度为O(1),
     * 其他情况，则会先进行数组的整体移动，然后再进行设置，主要耗时在数组的移动上了。
     * @param list
     * @return
     */
    public static long insertTest(List<Integer> list){
        long start = System.currentTimeMillis();
        int num =  list.size();
        for(int i=0;i<num;i++){
            list.add(i,9);
        }
        return System.currentTimeMillis()-start;
    }


    /**
     * 更新性能测试,在ArrayList中，更新耗时时间负责度为O(1)
     * 因为基于数组实现，所以能快速根据索引位置找到对应的元素进行更新
     * @param list
     * @return
     */
    public static long updateTest(List<Integer> list){
        long start = System.currentTimeMillis();
        for(int i=0;i<list.size();i++){
            list.set(i,i+1);
        }
        return System.currentTimeMillis()-start;
    }

    /**
     * 查询性能测试
     *  因为基于数组实现，所以能快速根据索引位置找到对应的元素
     * @param list
     * @return
     */
    public static long queryTest(List<Integer> list){
        long start = System.currentTimeMillis();
        for(int i=0;i<list.size();i++){
            list.get(i);
        }
        return System.currentTimeMillis()-start;
    }

    /**
     * 删除性能测试
     * 此操作的性能随删除元素的位置不同而不同，如果删除的是尾部元素，则无需数组整体移动，
     * 但是如果删除的是其他位置的话，则还是会进行数组的移动，这个操作比较耗时
     * @param list
     * @return
     */
    public static long deleteTest(List<Integer> list){
        long start = System.currentTimeMillis();
        for(int i=0;i<list.size();i++){
            list.remove(i);
        }
        return System.currentTimeMillis()-start;
    }



}
